import StreamZip from 'node-stream-zip';

export interface ZipEntry {
  name: string;
  isDirectory: boolean;
  size: number;
}

export class ZipEntries {
  private filename: string | undefined;
  private zipEntries: Array<ZipEntry>;

  constructor() {
    this.zipEntries = new Array<ZipEntry>();
  }

  private async readNewZip(filename: string) {
    const zip = new StreamZip.async({ file: filename, storeEntries: true });
    try {
      this.filename = filename;
      this.zipEntries = [];

      const entries = await zip.entries();
      for (const entry of Object.values(entries)) {
        let e = { name: entry.name, isDirectory: entry.isDirectory, size: entry.size };
        this.zipEntries.push(e);
      }
    } finally {
      await zip.close();
    }
  }

  reset() {
    this.filename = '';
    this.zipEntries = [];
  }

  async getEntries(filename: string, folder: string = '', ext: Array<string> = []) {
    // console.log(`get entries of ${filename} folder: ${folder}, ext: ${ext}`);
    if (filename !== this.filename) {
      await this.readNewZip(filename);
      this.filename = filename;
    }

    let reExt: string = '';
    for (let e of ext) {
      reExt += `|(${e})`;
    }
    if (reExt) {
      reExt = `((\/)${reExt})`;
    }
    let files: Array<ZipEntry> = new Array<ZipEntry>();
    for (const entry of this.zipEntries) {
      let regex = `^${folder}[^/]+`;
      if (reExt) {
        regex += `${reExt}$`;
      } else {
        regex += '\/?$';
      }
      let re = new RegExp(regex);
      if (re.test(entry.name)) {
        // console.log(`${regex} found: ${entry.name}`);
        files.push(entry);
      }
    }

    return files;
  }
}
